﻿
Imports osi.root.connector
Imports osi.root.delegates
Imports osi.root.formation
Imports osi.root.procedure
Imports osi.root.utils
Imports osi.service.argument

Public Module _secondary_resolve
    Public Function secondary_resolve_cast(Of T, PT, RT As T) _
                                          (ByVal v As var,
                                           ByVal type_name As String,
                                           ByVal f As Func(Of PT, pointer(Of RT), event_comb),
                                           ByVal o As pointer(Of T)) As event_comb
        assert(Not f Is Nothing)
        Dim p As pointer(Of PT) = Nothing
        Dim r As pointer(Of RT) = Nothing
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  If v Is Nothing Then
                                      Return False
                                  Else
                                      p = New pointer(Of PT)()
                                      If String.IsNullOrEmpty(type_name) Then
                                          ec = device_constructor.resolve_only(Of PT)(Nothing, v, p)
                                      Else
                                          v.bind(type_name)
                                          ec = device_constructor.resolve_only(Of PT)(v(type_name), v, p)
                                      End If
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  End If
                              End Function,
                              Function() As Boolean
                                  If ec.end_result() AndAlso
                                     assert(Not +p Is Nothing) Then
                                      r = New pointer(Of RT)()
                                      ec = f(+p, r)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         assert(Not +r Is Nothing) AndAlso
                                         eva(o, +r) AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function secondary_resolve_cast(Of T, PT, RT As T) _
                                          (ByVal v As var,
                                           ByVal type_name As String,
                                           ByVal f As _do_val_ref(Of PT, RT, Boolean),
                                           ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(v,
                                      type_name,
                                      Function(i As PT, r As pointer(Of RT)) As event_comb
                                          Return sync_async(Function() As Boolean
                                                                Dim x As RT = Nothing
                                                                If f(i, x) Then
                                                                    Return eva(r, x)
                                                                Else
                                                                    Return False
                                                                End If
                                                            End Function)
                                      End Function,
                                      o)
    End Function

    Public Function secondary_resolve_cast(Of T, PT, RT As T) _
                                          (ByVal v As var,
                                           ByVal type_name As String,
                                           ByVal f As Func(Of PT, RT),
                                           ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(v,
                                      type_name,
                                      Function(i As PT, r As pointer(Of RT)) As event_comb
                                          Return sync_async(Function() As Boolean
                                                                Return eva(r, f(i))
                                                            End Function)
                                      End Function,
                                      o)
    End Function

    Public Function secondary_resolve_cast(Of T, PT, RT As T) _
                                          (ByVal v As var,
                                           ByVal f As Func(Of PT, pointer(Of RT), event_comb),
                                           ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(v, Nothing, f, o)
    End Function

    Public Function secondary_resolve_cast(Of T, PT, RT As T) _
                                          (ByVal v As var,
                                           ByVal f As _do_val_ref(Of PT, RT, Boolean),
                                           ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(v, Nothing, f, o)
    End Function

    Public Function secondary_resolve_cast(Of T, PT, RT As T) _
                                          (ByVal v As var,
                                           ByVal f As Func(Of PT, RT),
                                           ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(v, Nothing, f, o)
    End Function

    Public Function secondary_resolve(Of T, PT) _
                                     (ByVal v As var,
                                      ByVal type_name As String,
                                      ByVal f As Func(Of PT, pointer(Of T), event_comb),
                                      ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(Of T, PT, T)(v, type_name, f, o)
    End Function

    Public Function secondary_resolve(Of T, PT) _
                                     (ByVal v As var,
                                      ByVal type_name As String,
                                      ByVal f As _do_val_ref(Of PT, T, Boolean),
                                      ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(Of T, PT, T)(v, type_name, f, o)
    End Function

    Public Function secondary_resolve(Of T, PT) _
                                     (ByVal v As var,
                                      ByVal type_name As String,
                                      ByVal f As Func(Of PT, T),
                                      ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(Of T, PT, T)(v, type_name, f, o)
    End Function

    Public Function secondary_resolve(Of T, PT) _
                                     (ByVal v As var,
                                      ByVal f As Func(Of PT, pointer(Of T), event_comb),
                                      ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(Of T, PT, T)(v, f, o)
    End Function

    Public Function secondary_resolve(Of T, PT) _
                                     (ByVal v As var,
                                      ByVal f As _do_val_ref(Of PT, T, Boolean),
                                      ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(Of T, PT, T)(v, f, o)
    End Function

    Public Function secondary_resolve(Of T, PT) _
                                     (ByVal v As var,
                                      ByVal f As Func(Of PT, T),
                                      ByVal o As pointer(Of T)) As event_comb
        Return secondary_resolve_cast(Of T, PT, T)(v, f, o)
    End Function
End Module
